//
//  CRCTests.m
//  Clock Signal
//
//  Created by Thomas Harte on 27/12/2016.
//  Copyright 2016 Thomas Harte. All rights reserved.
//

#import <XCTest/XCTest.h>
#include "CRC.hpp"
#include <string>

@interface CRCTests : XCTestCase
@end

@implementation CRCTests

- (uint16_t)crcOfData:(const uint8_t *)data length:(size_t)length generator:(CRC::CCITT &)generator {
	return generator.crc_of(data, data+length);
}

- (void)testIDMark {
	static constexpr uint8_t IDMark[] = {
		0xa1, 0xa1, 0xa1, 0xfe, 0x00, 0x00, 0x01, 0x01
	};
	static constexpr uint16_t crc = 0xfa0c;
	const uint16_t computedCRC = CRC::CCITT::crc_of(std::begin(IDMark), std::end(IDMark));

	XCTAssert(computedCRC == crc, @"Calculated CRC should have been %04x, was %04x", crc, computedCRC);
}

- (void)testData {
	static constexpr uint8_t sectorData[] = {
		0xa1, 0xa1, 0xa1, 0xfb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x53, 0x45, 0x44, 0x4f,
		0x52, 0x49, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x53, 0x45, 0x44, 0x4f, 0x52, 0x49, 0x43, 0x20, 0x56, 0x31, 0x2e, 0x30,
		0x30, 0x36, 0x20, 0x30, 0x31, 0x2f, 0x30, 0x31, 0x2f, 0x38, 0x36, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20
	};
	static constexpr uint16_t crc = 0x4de7;
	uint16_t computedCRC = CRC::CCITT::crc_of(std::begin(sectorData), std::end(sectorData));

	XCTAssert(computedCRC == crc, @"Calculated CRC should have been %04x, was %04x", crc, computedCRC);
}

- (void)testCCITTCheck {
	static constexpr char testString[] = "123456789";
	XCTAssertEqual(CRC::CCITT::crc_of(std::begin(testString), std::end(testString) - 1), 0x29b1);
}

- (void)testCRC32Check {
	static constexpr char testString[] = "123456789";
	XCTAssertEqual(CRC::CRC32::crc_of(std::begin(testString), std::end(testString) - 1), 0xcbf43926);
}

@end
